[BITS 16]
[CPU 286]

global __print_str

%ifndef BCC
[SEGMENT _TEXT class=CODE]
%else
[SECTION .text]
%endif

;*******************************************************************************
;**  Fonction interne d'affichage d'une chaine                                **
;**  > ds:bp : la chaine                                                      **
;**  > cs:si : la police                                                      **
;**  > es:di : le buffer                                                      **
;**  > bx  : la ligne   (orgine bas droite)                                   **
;**  > cx  : la colonne (en pixels)                                           **
;**  > ax  : la largeur du buffer (en octet)                                  **
;*******************************************************************************
__print_str:
push bp
  push ax
; calculate the base offset in the buffer by multiplying the line by the buffer width
    mul bx
    add di,ax
  pop ax
  .boucle:
    push si
      push cx
; get the character offset in the font
        mov cl,[ds:bp]
        sub cl,' '
        push ax
          mov al,cl
; get the height of the font
          mov ah,[cs:si]
; save it in bl, it is going to be used when we display the sprite
          mov bl,ah
; multiply the character position in the font by its height to get the address of the letter
; don't forget that for each letter, we have another byte for the height of the font
          inc ah
          mul ah
; add to the base address of the font
          add si,ax
; skip the first byte (heigth of the font)
          inc si
        pop ax
      pop cx
; substract the width of the current letter from the current column
      xor dh,dh
      mov dl,[cs:si]
      sub cx,dx
      push cx
        push di
          ;pos dans le buffer
          mov dx,cx
          shr dx,3
          add di,dx
; calculate the offset in bits for the current letter
          mov dx,cx
          and dx,7
          mov bh,dl
; get the width of the letter
          mov dh,[cs:si]
; skip the width to get the sprite
          inc si
;** AFFICHAGE SPRITE
; es:di : destination
; cs:si : address of the letter to display
; bl : the heigth of the font
; dh : the width of the font
; ch : offset in bits for the destination
            mov ch,bh
; what's the offset ?
            mov cl,15
            sub cl,dh

            .spr_boucle:
              push ax
; load the data
                xor al,al
                mov ah,[cs:si]

; Put the data in the lower bits of ax
                shr ax,cl

                push di
; move dh bits of ax to es:di + ch
                  ins ch,dh
; ins modified di and ch : reload them
                  mov ch,bh
                pop di
              pop ax

; next line
              add di,ax
              inc si
; bl was saved at the begining of this function
            dec bl
            jnz .spr_boucle

;** FIN AFFICHAGE SPRITE
        pop di
; next letter
        inc bp
      pop cx
    pop si
; stop on the \0 character
    cmp byte [ds:bp],0
  jne .boucle
pop bp
ret

